using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using twistmachinev2.CommonUse;
using twistmachinev2.OPCUA;
using twistmachinev2.TwistControl;

namespace twistmachinev2
{
    public partial class FrmIO : BaseOpcUaForm
    {

        public FrmIO()
        {
            InitializeComponent();
            InitialDataModel();
            RegisterDataBindingButtonEvents();
        }

        //绑定DataModel操作
        private void InitialDataModel()
        {
            var dataModel = GetDataModel("TwistMachine");

            // 遍历所有控件，为DataBindingStatusCircle类型的控件设置DataModel
            SetDataModelForControls(this, dataModel);
        }

        /// <summary>
        /// 递归遍历控件及其子控件，为DataBindingStatusCircle类型的控件设置DataModel
        /// </summary>
        /// <param name="parent">父控件</param>
        /// <param name="dataModel">数据模型</param>
        private void SetDataModelForControls(Control parent, DynamicDataModel dataModel)
        {
            foreach (Control control in parent.Controls)
            {
                // 检查控件类型是否为DataBindingStatusCircle
                if (control is TwistControl.DataBindingStatusCircle statusCircle)
                {
                    statusCircle.DataModel = dataModel;
                }
                // 检查控件类型是否为DataBindingTextBox
                else if (control is TwistControl.DataBindingTextBox textBox)
                {
                    textBox.DataModel = dataModel;
                }
                else if (control is TwistControl.DataBindingButton button)
                {
                    button.DataModel = dataModel;
                }

                // 递归处理子控件
                if (control.HasChildren)
                {
                    SetDataModelForControls(control, dataModel);
                }
            }
        }
        //可以监听数据的变化进行操作
        protected override void OnDataChangedOnUIThread(string nodeId, object value)
        {
            //switch (nodeId)
            //{
            //    case "ns=2;s=Motor.Start":
            //        // 处理电机启动状态变化
            //        break;
            //    case "ns=2;s=Motor.Speed":
            //        // 处理电机转速变化
            //        break;
            //}
        }
        /// <summary>
        /// 注册xtraTabPage2中所有DataBindingButton控件的点击事件
        /// </summary>
        private void RegisterDataBindingButtonEvents()
        {
            // 遍历xtraTabPage2中的所有DataBindingButton控件
            RegisterDataBindingButtonEventsRecursive(xtraTabPage2);
        }

        /// <summary>
        /// 递归遍历控件并注册DataBindingButton的点击事件
        /// </summary>
        /// <param name="parent">父控件</param>
        private void RegisterDataBindingButtonEventsRecursive(Control parent)
        {
            foreach (Control control in parent.Controls)
            {
                // 检查控件类型是否为DataBindingButton
                if (control is TwistControl.DataBindingButton dataBindingButton)
                {
                    // 注册点击事件（保留但注释掉相关逻辑）
                    dataBindingButton.Click += databindButtonClick_Click;

                    // 注册鼠标按下和松开事件
                    dataBindingButton.MouseDown += DataBindingButton_MouseDown;
                    dataBindingButton.MouseUp += DataBindingButton_MouseUp;
                }

                // 递归处理子控件
                if (control.HasChildren)
                {
                    RegisterDataBindingButtonEventsRecursive(control);
                }
            }
        }

        //IO界面按钮点击事件（保留代码但注释掉相关逻辑）
        private async void databindButtonClick_Click(object sender, EventArgs e)
        {
            // 原有的Click事件逻辑已注释，现在使用MouseDown/MouseUp事件
            /*
            // 将sender转换为DataBindingButton
            if (sender is TwistControl.DataBindingButton button)
            {
                // 获取PropertyName属性
                string propertyName = button.PropertyName;
                
                if (!string.IsNullOrEmpty(propertyName))
                {
                    // 根据PropertyName获取对应的OPC UA NodeId
                    string nodeId = GetNodeIdByPropertyName(propertyName);
                    
                    if (!string.IsNullOrEmpty(nodeId))
                    {
                        // 按钮点击
                        
                        // 从控件DataModel中获取当前值并进行取反操作
                        await ToggleOpcUaNodeValue(button, nodeId);
                    }
                    else
                    {
                        // 未找到对应的NodeId
                    }
                }
                else
                {
                    // 按钮的PropertyName为空
                }
            }
            */
        }

        /// <summary>
        /// 根据PropertyName获取对应的OPC UA NodeId
        /// </summary>
        /// <param name="propertyName">属性名称</param>
        /// <returns>NodeId字符串</returns>
        private string GetNodeIdByPropertyName(string propertyName)
        {
            try
            {
                // 获取OPC UA配置服务
                var configService = OpcUaServiceManager.Instance.ConfigService;
                if (configService == null)
                {
                    // OPC UA配置服务未初始化
                    return null;
                }

                // 获取所有节点配置
                var allNodes = configService.GetAllNodes();
                if (allNodes == null || allNodes.Count == 0)
                {
                    // 未找到任何OPC UA节点配置
                    return null;
                }

                // 根据PropertyName查找对应的节点配置
                var nodeConfig = allNodes.FirstOrDefault(n => n.PropertyName == propertyName);
                if (nodeConfig == null)
                {
                    // 未找到对应的节点配置
                    return null;
                }

                return nodeConfig.NodeId;
            }
            catch (Exception ex)
            {
                LogManager.LogError($"获取PropertyName '{propertyName}' 对应的NodeId时发生异常", ex);
                return null;
            }
        }

        /// <summary>
        /// 从控件DataModel中获取当前值并进行取反写入操作
        /// </summary>
        /// <param name="button">DataBindingButton控件</param>
        /// <param name="nodeId">节点ID</param>
        private async Task ToggleOpcUaNodeValue(TwistControl.DataBindingButton button, string nodeId)
        {
            try
            {
                // 检查OPC UA服务管理器是否已初始化
                if (!OpcUaServiceManager.Instance.IsInitialized)
                {
                    LogManager.LogError("OPC UA服务管理器未初始化");
                    toolStripStatusLabel1.Text = "OPC UA服务未初始化";
                    return;
                }

                // 从控件的DataModel中获取当前值
                bool currentValue = false;
                if (button.DataModel != null && !string.IsNullOrEmpty(button.PropertyName))
                {
                    var value = button.DataModel.GetValue(button.PropertyName);
                    if (value is bool boolValue)
                    {
                        currentValue = boolValue;
                    }
                    else if (value != null)
                    {
                        // 尝试将其他类型转换为bool
                        bool.TryParse(value.ToString(), out currentValue);
                    }
                }

                // 取反操作
                bool newValue = !currentValue;
                // 节点当前值，将写入新值

                // 执行写入操作
                var writeResult = await OpcUaServiceManager.Instance.WriteNodeAsync(nodeId, newValue);
                if (writeResult.IsSuccess)
                {
                    // 成功写入数据到节点
                    toolStripStatusLabel1.Text = $"取反写入成功 - 节点: {nodeId}, 值: {newValue}";
                }
                else
                {
                    LogManager.LogError($"写入数据到节点 {nodeId} 失败: {writeResult.Message}");
                    toolStripStatusLabel1.Text = $"写入失败 - {writeResult.Message}";
                }
            }
            catch (Exception ex)
            {
                LogManager.LogError($"取反写入节点 {nodeId} 时发生异常", ex);
                toolStripStatusLabel1.Text = "取反写入异常";
            }
        }

        /// <summary>
        /// 向OPC UA节点写入数据
        /// </summary>
        /// <param name="nodeId">节点ID</param>
        /// <param name="value">要写入的值</param>
        private async void WriteToOpcUaNode(string nodeId, object value)
        {
            try
            {
                // 检查OPC UA服务管理器是否已初始化
                if (!OpcUaServiceManager.Instance.IsInitialized)
                {
                    LogManager.LogError("OPC UA服务管理器未初始化");
                    toolStripStatusLabel1.Text = "OPC UA服务未初始化";
                    return;
                }

                // 执行写入操作
                var result = await OpcUaServiceManager.Instance.WriteNodeAsync(nodeId, value);
                if (result.IsSuccess)
                {
                    // 成功写入数据到节点
                    toolStripStatusLabel1.Text = $"写入成功 - 节点: {nodeId}";
                }
                else
                {
                    LogManager.LogError($"写入数据到节点 {nodeId} 失败: {result.Message}");
                    toolStripStatusLabel1.Text = $"写入失败 - {result.Message}";
                }
            }
            catch (Exception ex)
            {
                LogManager.LogError($"写入数据到节点 {nodeId} 时发生异常", ex);
                toolStripStatusLabel1.Text = "写入异常";
            }
        }

        /// <summary>
        /// DataBindingButton鼠标按下事件 - 发送1
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void DataBindingButton_MouseDown(object sender, MouseEventArgs e)
        {
            // 只处理左键按下
            if (e.Button == MouseButtons.Left && sender is TwistControl.DataBindingButton button)
            {
                string propertyName = button.PropertyName;

                if (!string.IsNullOrEmpty(propertyName))
                {
                    // 根据PropertyName获取对应的OPC UA NodeId
                    string nodeId = GetNodeIdByPropertyName(propertyName);

                    if (!string.IsNullOrEmpty(nodeId))
                    {
                        // 按钮按下

                        // 发送1
                        await WriteValueToOpcUaNode(nodeId, true);
                    }
                    else
                    {
                        // 未找到对应的NodeId
                    }
                }
                else
                {
                    // 按钮的PropertyName为空
                }
            }
        }

        /// <summary>
        /// DataBindingButton鼠标松开事件 - 发送0
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void DataBindingButton_MouseUp(object sender, MouseEventArgs e)
        {
            // 只处理左键松开
            if (e.Button == MouseButtons.Left && sender is TwistControl.DataBindingButton button)
            {
                string propertyName = button.PropertyName;

                if (!string.IsNullOrEmpty(propertyName))
                {
                    // 根据PropertyName获取对应的OPC UA NodeId
                    string nodeId = GetNodeIdByPropertyName(propertyName);

                    if (!string.IsNullOrEmpty(nodeId))
                    {
                        // 按钮松开

                        // 发送0
                        await WriteValueToOpcUaNode(nodeId, false);
                    }
                    else
                    {
                        // 未找到对应的NodeId
                    }
                }
                else
                {
                    // 按钮的PropertyName为空
                }
            }
        }

        /// <summary>
        /// 向OPC UA节点写入指定值
        /// </summary>
        /// <param name="nodeId">节点ID</param>
        /// <param name="value">要写入的值</param>
        private async Task WriteValueToOpcUaNode(string nodeId, object value)
        {
            try
            {
                // 检查OPC UA服务管理器是否已初始化
                if (!OpcUaServiceManager.Instance.IsInitialized)
                {
                    LogManager.LogError("OPC UA服务管理器未初始化");
                    toolStripStatusLabel1.Text = "OPC UA服务未初始化";
                    return;
                }

                // 执行写入操作
                var result = await OpcUaServiceManager.Instance.WriteNodeAsync(nodeId, value);
                if (result.IsSuccess)
                {
                    // 成功写入数据到节点
                    toolStripStatusLabel1.Text = $"写入成功 - 节点: {nodeId}, 值: {value}";
                }
                else
                {
                    LogManager.LogError($"写入数据到节点 {nodeId} 失败: {result.Message}");
                    toolStripStatusLabel1.Text = $"写入失败 - {result.Message}";
                }
            }
            catch (Exception ex)
            {
                LogManager.LogError($"写入数据到节点 {nodeId} 时发生异常", ex);
                toolStripStatusLabel1.Text = "写入异常";
            }
        }



        private async void WriteToOpcUaNodeSelf(string propertyName, object value)
        {
            string nodeId = GetNodeIdByPropertyName(propertyName);
            if (!string.IsNullOrEmpty(nodeId))
            {
                await WriteValueToOpcUaNode(nodeId, value);
            }
        }

        private void btnSendDiandong_Click(object sender, EventArgs e)
        {
            WriteToOpcUaNodeSelf(tbApplication_ZX_HMI_JT_XZcz_I_JOGsd.PropertyName, tbApplication_ZX_HMI_JT_XZcz_I_JOGsd.Text);
        }

        private void btnJiaJianTime_Click(object sender, EventArgs e)
        {
            WriteToOpcUaNodeSelf(tbApplication_ZX_HMI_JT_XZcz_I_AccDoc.PropertyName, tbApplication_ZX_HMI_JT_XZcz_I_AccDoc.Text);
        }

        private void btnDingweiSudu_Click(object sender, EventArgs e)
        {
            WriteToOpcUaNodeSelf(tbApplication_ZX_HMI_JT_XZInOut_IO_DWVic.PropertyName, tbApplication_ZX_HMI_JT_XZInOut_IO_DWVic.Text);
        }

        private void btnSendDiandong2_Click(object sender, EventArgs e)
        {
            WriteToOpcUaNodeSelf(dataBindingTextBox3.PropertyName, dataBindingTextBox3.Text);
        }

        private void btnJiaJianTime2_Click(object sender, EventArgs e)
        {
            WriteToOpcUaNodeSelf(dataBindingTextBox4.PropertyName, dataBindingTextBox4.Text);
        }

        private void btnDingweiSudu2_Click(object sender, EventArgs e)
        {
            WriteToOpcUaNodeSelf(dataBindingTextBox2.PropertyName, dataBindingTextBox2.Text);
        }
    }

}